package org.joy;

import com.oracle.bmc.auth.InstancePrincipalsAuthenticationDetailsProvider;
import com.oracle.bmc.objectstorage.ObjectStorage;
import com.oracle.bmc.objectstorage.ObjectStorageClient;
import com.oracle.bmc.objectstorage.model.CreatePreauthenticatedRequestDetails;
import com.oracle.bmc.objectstorage.requests.CreatePreauthenticatedRequestRequest;
import com.oracle.bmc.objectstorage.responses.CreatePreauthenticatedRequestResponse;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class OssClientPreAuth {
    public static void main(String[] args) throws UnsupportedEncodingException {
        final String regionid = "ap-seoul-1";
        final String bucketname = "buckettest";
        final String objectname = "public/dd.jpeg";
        final String preauth = "KT8zWkrb7in9LeMQjqUW5p-NZbZhDJ8uIYiEcfEF5Xq_hyILoyYW7sBOJmfp37wK";   // public目录的授权码
//        final InstancePrincipalsAuthenticationDetailsProvider provider =  InstancePrincipalsAuthenticationDetailsProvider.builder().build();
        final String compartmentId = "ocid1.tenancy.oc1..aaaaaaaamdypr7vjm7e6ftrjngh3a3ffyj63cftfh4giko37zlderg4tfnmq";
//        ObjectStorage client = new ObjectStorageClient(provider);
//
//        GetNamespaceResponse namespaceResponse =
//                client.getNamespace(GetNamespaceRequest.builder().build());
//        String namespaceName = namespaceResponse.getValue();
//        System.out.println("Using namespace: " + namespaceName);

        String namespaceName = "cnjxmruwj0jf";
        String encodeobjectname = URLEncoder.encode(objectname, "UTF-8");
        String objecturl = readFromPrivateBucket(regionid,preauth,namespaceName,bucketname,encodeobjectname);
        System.out.println(objecturl);

//
//        Builder listBucketsBuilder =
//                ListBucketsRequest.builder()
//                        .namespaceName(namespaceName)
//                        .compartmentId(compartmentId);
//
//        String nextToken = null;
//        do {
//            listBucketsBuilder.page(nextToken);
//            ListBucketsResponse listBucketsResponse =
//                    client.listBuckets(listBucketsBuilder.build());
//            for (BucketSummary bucket : listBucketsResponse.getItems()) {
//                System.out.println("Found bucket: " + bucket.getName());
//            }
//            nextToken = listBucketsResponse.getOpcNextPage();
//        } while (nextToken != null);
//
//
//
//        String str = "String与InputStream相互转换";
//        InputStream in_nocode   =   new ByteArrayInputStream(str.getBytes());
//        Map<String ,String > objmeta = new HashMap<>();
//        objmeta.put("name","joy");
//        PutObjectRequest putObjectRequest = PutObjectRequest.builder()
//                .putObjectBody(in_nocode)
//                .opcMeta(objmeta)
//                .bucketName("bucket-20230725-11301")
//                .contentLength((long) str.getBytes().length)
//                .namespaceName(namespaceName)
//                .objectName("demo").build();
//        PutObjectResponse putObjectResponse = client.putObject(putObjectRequest);
//        System.out.println(putObjectResponse);
    }


    // public bucket  read object by url
    public static String readFromPublicBucket( String regionid, String namespace,String bucketname, String objectname){
        String urlformat = "https://%s.objectstorage.%s.oci.customer-oci.com/n/%s/b/%s/o/%s";
        String objecturl = String.format(urlformat,namespace,regionid,namespace,bucketname,objectname);
        return objecturl;
    }

    // public bucket write object
    public static void writePublicBucket(){
        //TODO  though api
    }


    //  private  bucket write and read object by  url (with pre auth)
    public static  String  createReadPreauthication(){
        String namespace = "cnjxmruwj0jf";
        final String regionid = "ap-seoul-1";
        final String bucketname = "buckettest";
        final String objectname = "public/";
        InstancePrincipalsAuthenticationDetailsProvider provider =  InstancePrincipalsAuthenticationDetailsProvider.builder().build();
        ObjectStorage client = new ObjectStorageClient(provider);

        Date now = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        calendar.add(Calendar.MINUTE, 30);
        Date expiredate = calendar.getTime();

        CreatePreauthenticatedRequestDetails createPreauthenticatedRequestDetails = CreatePreauthenticatedRequestDetails.builder()
                .name(bucketname)
                .objectName(objectname)
                .accessType(CreatePreauthenticatedRequestDetails.AccessType.ObjectWrite)
                .timeExpires(expiredate).build();

        CreatePreauthenticatedRequestRequest createPreauthenticatedRequestRequest = CreatePreauthenticatedRequestRequest.builder()
                .namespaceName(namespace)
                .bucketName(bucketname)
                .createPreauthenticatedRequestDetails(createPreauthenticatedRequestDetails).build();

        /* Send request to the Client */
        CreatePreauthenticatedRequestResponse response = client.createPreauthenticatedRequest(createPreauthenticatedRequestRequest);
        String access_url = response.getPreauthenticatedRequest().getAccessUri();
        String urlformat = "https://%s.objectstorage.%s.oci.customer-oci.com%s";
        String objecturl = String.format(urlformat,namespace,regionid,access_url);
        return objecturl;
    }

    // read object though pre-authication url
    // preauth  only read 是bucket内部fold的签名  需要手动创建9999
    public static String readFromPrivateBucket( String regionid,String preauth, String namespace,String bucketname, String objectname){
        String urlformat = "https://%s.objectstorage.%s.oci.customer-oci.com/p/%s/n/%s/b/%s/o/%s";
        String objecturl = String.format(urlformat,namespace,regionid,preauth,namespace,bucketname,objectname);
        return objecturl;
    }

    public static  void  putbySignalURL(){

    }

    public static  void  deletebySignalURL(){

    }


    private static String getCurrentDate(){
        final Date currentTime = new Date();
        final SimpleDateFormat sdf =
                new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss z", Locale.ENGLISH);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        return sdf.format(currentTime);
    }
    private static String signSHA256RSA(String input, String strPk) throws Exception {
        // Remove markers and new line characters in private key
        String realPK = strPk.replaceAll("-----END PRIVATE KEY-----", "")
                .replaceAll("-----BEGIN PRIVATE KEY-----", "")
                .replaceAll("\n", "");

        byte[] b1 = Base64.getDecoder().decode(realPK);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b1);
        KeyFactory kf = KeyFactory.getInstance("RSA");

        Signature privateSignature = Signature.getInstance("SHA256withRSA");
        privateSignature.initSign(kf.generatePrivate(spec));
        privateSignature.update(input.getBytes("UTF-8"));
        byte[] s = privateSignature.sign();
        return Base64.getEncoder().encodeToString(s);
    }

    public static void PutSignatures() throws Exception{
        String tenancyid = "ocid1.tenancy.oc1..aaaaaaaamdypr7vjm7e6ftrjngh3a3ffyj63cftfh4giko37zlderg4tfnmq";
        String userid = "ocid1.user.oc1..aaaaaaaah24musimppesv3ucptkthgto4o6mowq5jktchtuhakopqvlae4pa";
        String fingerprint = "d7:33:6c:3b:fa:a0:e1:c6:bf:b0:0e:84:93:bb:6d:67";
        String rsa_priv_key="-----BEGIN PRIVATE KEY-----\n" +
                "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCfuAKtLq6IFkkI\n" +
                "mSyGhtrQW6IEhsNB5onu/We5UJ5t5wRDWyzMPV298MiDTZmQmwti/VhjSu1D0sBu\n" +
                "+qe+PXtOItegsvIUM5UgjV/gB/sFCU70anbSu/EIvdNwT2wguHa5Lrxhr1MwyJs8\n" +
                "DnZR7yNFxkw0dDWHnP8m01twP7vN5YJGYdX46W56dnyr0j0fzHPI34FjpTIqpUbJ\n" +
                "vgrr+fmvD0PwqRW0UwstI6WIxDoiQ1XKX1Uf6CBISH1xkze/gBh587glvEeBkb7X\n" +
                "4SlhSyOZekfkOrmw54DK9Zx7yIyH3BVDhlDFZSAcMme+u0LC2tNUCsyjoWhElL6z\n" +
                "hUnekd5NAgMBAAECggEAGtCvClprDQgIzPvCgPeFJzQrOG1TvO2yvMAouPEzGCqQ\n" +
                "Car2E3g+E9SoJXtSy/dr6vuz6j+7JAbvLfLBVOxHlm+9GgrRH9klMWjq7tcIKulM\n" +
                "KzbwqiLJrfkI1bNP6RJvRFn3YMMpyWf0wBmBffITTvSi+K+GCTWvlNopYOgiZMfe\n" +
                "TmbNjpTvvfQhi24/V/002beRYpilhKVPZWDDjeutXVyVIak9HGC4SZ3/oNggy4zD\n" +
                "TBRQGHeu7RKIT62o340vp2eF4j8rPrWv3a/1mxygkVWoKqldnRLj3jGcwQirgDvU\n" +
                "H/atCgL4p7gi2Fr5iGGeOoXXDH1rzIy99PBZGWy1IQKBgQDhz2eD6uFakENpCWTx\n" +
                "FgF3Zb44+dIcLeBwke318CZGvNrmx3nXrhAkrItG6pB6AlkCR6K9OaakfqNxduEj\n" +
                "lATHxCoX0HaOM9qzOg1x//a2W+ODkY3G6eSDfkB68ZeUuPgDBIxoCcAUm6yPHJFG\n" +
                "BGypFQxziyHcyQjJEohs8tw0uQKBgQC1Eo683KAjqzJ1zjgXkSrM8ugRhi9/TreS\n" +
                "8Fuol8ykhSIKsvuSrS2kiMc+4uPiqNMz9xPifx7+XUJdefyWkrCjFScCx0y3MGya\n" +
                "UuPbO2ZxPkgdZwtnSQMzQJ8Bgp6uCF/dBHFP50TYoCuDU9SORE00pJKuYfBzK39u\n" +
                "Le2rTICUNQKBgDYWigMNNeGNgLgeKfGdhchltITNQkjBrGsKaWdpmKGFByIUUdkZ\n" +
                "toAyXEImWWkAOvXS1uZgcswgEWJSSWdOQz7ee/6sTlmNjis0Ephl6WCQ7hRLvxwQ\n" +
                "Vk4w5Z0NVXOoQq/mXQNmon3NNC4rd5i/4o81nX/nqbrK5LHVIJyIJ7rxAoGBAISR\n" +
                "IpmY+VFD7HydTynJ6UkFaewyjqGpEvNsL979zCCDLAojQdYAHhOA5EbhPDBco8w+\n" +
                "z3sa0Kkvw//F6Kygltu/B8GcAkl4FXrixtlh4r1z+L42C/5BUSt72y3y4JPPo8ef\n" +
                "kgoK6reihFjwzgSectvgxVcQc0cOiIw06fVo3BYlAoGAQKv0K9kJ5IlrnG4TyLOe\n" +
                "OnYNtNxAvn4JOMbpBEVb/dHGhU3AsSK+k0Tkx+gJFZ94H8IrjzPkd+F2PS82INhV\n" +
                "EADg8EhXOAyyYredCKRsIAmZWBGY+cLgT1S0o5FxJvIx82IMwBIi8nMqB0yDWWC9\n" +
                "dBLW+/8xlKScI+AfrflQVz4=\n" +
                "-----END PRIVATE KEY-----";

        String  apiKeyId =String.format("%s/%s/%s",tenancyid, userid, fingerprint);

        String host= "objectstorage.ap-singapore-1.oraclecloud.com";

        String path = "/n/cnjxmruwj0jf/b/buckettest/o/demo3";
        String method = "PUT";
        String currentDate = getCurrentDate();

        InputStream input = OssClientPreAuth.class.getResourceAsStream("/data.json");
        byte[] data = input.readAllBytes();

        String contentlength = Integer.toString(data.length);
        String requestTargetHeader = String.format("(request-target): %s %s", method.toLowerCase(), path);
        String dateHeader = String.format("date: %s", currentDate);
        String hostHeader = String.format("host: %s", host);
        String contentlengthheader = String.format("content-length: %s", contentlength);
        String headers = "(request-target) date host content-length";

        String[] header= { requestTargetHeader,dateHeader , hostHeader,contentlengthheader};
        String signString = Arrays.stream(header).filter(string -> !string.isEmpty()).collect(Collectors.joining("\n"));
        System.out.println(signString);
        String base64EncodedSignature = signSHA256RSA(signString,rsa_priv_key);
        String Authorization  = String.format("Signature version=\"1\",keyId=\"%s\",algorithm=\"rsa-sha256\",headers=\"%s\",signature=\"%s\"",apiKeyId, headers, base64EncodedSignature);
        System.out.println(Authorization);

    }
}
